import ProLayout, {
    MenuDataItem,
    BasicLayoutProps as ProLayoutProps,
    Settings,
} from '@ant-design/pro-layout';
import React, { useEffect, useState } from 'react';
import { connect } from 'dva';
import { formatMessage } from 'umi-plugin-react/locale';

import _ from 'lodash';
import Media from 'react-media';

import { Modal } from 'antd';
import { ExclamationCircleOutlined, createFromIconfontCN } from '@ant-design/icons';

import { addTab } from '@/utils/utils';
import Authorized from '@/utils/Authorized';
import RightContent from '@/components/GlobalHeader/RightContent';
import { ConnectState, Dispatch } from '@/models/connect';
import NoRights from '../pages/noRights';
import 'react-intl';

const PATHNAME = window.location.pathname;
const pathname = PATHNAME.split('/')[2] || '/';

const MyIcon = createFromIconfontCN({
    scriptUrl: '//at.alicdn.com/t/font_1430304_sep3ov2yd2.js', // 在 iconfont.cn 上生成
});

export interface BasicLayoutProps extends ProLayoutProps {
    breadcrumbNameMap: {
        [path: string]: MenuDataItem;
    };
    collapsed: boolean;
    settings: Settings;
    dispatch: Dispatch;
    menuGroup: any;
    showMore: boolean;
}

export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & {
    breadcrumbNameMap: {
        [path: string]: MenuDataItem;
    };
};

/**
 * use Authorized check all menu item
 */
const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] => menuList.map((item) => {
    const localItem = {
        ...item,
        children: item.children ? menuDataRender(item.children) : [],
    };
    return Authorized.check(item.authority, localItem, null) as MenuDataItem;
});

const welcomeElem = (
    <div style={{ marginLeft: 24, marginTop: 24 }}>Welcome, 请点击左侧菜单开启使用！</div>
);

/** 判断访问权限 */
const queryAccessPermissions = (menuGroup: any, children: any) => {
    let request: any = welcomeElem;
    for (let i = 0; i < menuGroup.length; i += 1) {
        if (request === children) break;
        const { children: subMenu = [] } = menuGroup[i];
        for (let j = 0; j < subMenu.length; j += 1) {
            if (subMenu[j].path.indexOf(pathname) >= 0) {
                request = children;
                break;
            }
        }
        request = request || <NoRights />;
    }
    return request;
};

function handleMenuItem(dispatch: any, menuItem: any) {
    const {
        id,
        parent_id,
        name,
        path,
    } = menuItem;

    if (parent_id === 0) {
        dispatch({
            type: 'menu/fetchMenu',
            payload: { parent_id: id },
        }).then((res: any) => {
            if (res) {
                const menu = res.body.menu_list[0];
                addTab(dispatch, { name: menu.name, url: menu.uri, isTopMenu: true });
            }
        });
    } else {
        const currentUrl = window.location.pathname;
        if (currentUrl.indexOf('/add') > 0 || currentUrl.indexOf('/edit') > 0) {
            Modal.confirm({
                title: '警告！',
                icon: <ExclamationCircleOutlined />,
                content: '您可能有修改尚未保存，确定要跳转新页面吗？',
                okText: '确认',
                cancelText: '取消',
                onOk: () => addTab(dispatch, { name, url: path, isTopMenu: true }),
            });
        } else {
            addTab(dispatch, { name, url: path, isTopMenu: true });
        }
    }
}

function hideMore(dispatch: any, showMore: boolean) {
    if (showMore) {
        dispatch({
            type: 'global/setMore',
            payload: { isShow: false },
        });
    }
}

const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
    const [menuData, setMenuData] = useState([]);
    const {
        dispatch,
        children,
        collapsed,
        settings,
        menuGroup,
        showMore,
    } = props;
    /**
     * 监听屏幕宽度变化事件
    */
    const handleChangeScreen = (e: any) => {
        const window = e.target || e;
        const { innerWidth } = window;
        const main = document.getElementsByTagName('main')[0];
        const content: any = document.getElementsByClassName('ant-pro-basicLayout-children-content-wrap')[0];
        let screen = 'md';
        if (innerWidth <= 1000) {
            main.style.overflowX = 'auto';
            content.style.width = '1200px';
            screen = 'sm';
        } else if (innerWidth > 1000 && innerWidth < 1499) {
            screen = 'md';
            main.style.overflowX = 'inherit';
            content.style.width = '100%';
        } else if (innerWidth >= 1500) {
            main.style.overflowX = 'inherit';
            content.style.width = '100%';
            screen = 'lg';
        }
        dispatch({
            type: 'global/setScreen',
            payload: {
                screen,
            },
        });
    };

    /**
     * constructor
     */
    useEffect(() => {
        if (dispatch) {
            dispatch({
                type: 'user/fetchCurrent',
            });

            dispatch({
                type: 'settings/getSetting',
            });

            dispatch({
                type: 'menu/fetchMenu',
                payload: {
                    parent_id: 0,
                    pathname: 'default',
                },
            });
        }
        const aside = document.getElementsByTagName('aside')[0];
        aside.onselectstart = () => false;
        window.addEventListener('resize', handleChangeScreen);
        handleChangeScreen(window);
    }, [dispatch]);

    const handleMenuCollapse = (payload: boolean): void => dispatch
        && dispatch({
            type: 'global/changeLayoutCollapsed',
            payload,
        });

    const setScreen = (screen: string) => {
        dispatch({
            type: 'global/setScreen',
            payload: { screen },
        });
    };

    menuGroup.forEach((menu: any) => {
        menu.path = menu.target_tab;
        menu.iconName = menu.target_tab.indexOf('/') >= 0 ? menu.target_tab.split('/')[1] : menu.target_tab;
        menu.icon = <MyIcon type={`icon${menu.iconName}`} />;

        if (menu.children) {
            menu.children.forEach((subMenu: any) => {
                subMenu.path = subMenu.uri;
            });
        }
    });

    const childrenElem = queryAccessPermissions(menuGroup, children);
    if ((menuGroup.length > 0 && menuData.length <= 0) || !_.isEqual(menuGroup, menuData)) {
        setMenuData(menuGroup || []);
    }

    window.onerror = (errorMessage: any) => {
        if (errorMessage.includes('Loading chunk')) {
            window.location.reload();
        }
    };

    return (
        <div onClick={() => hideMore(dispatch, showMore)} style={{ height: '100%' }}>
            <Media
                queries={{
                    small: '(max-width: 599px)',
                    medium: '(min-width: 600px) and (max-width: 1499px)',
                    large: '(min-width: 1500px)',
                }}
                onChange={(matches: any) => (
                    <>
                        {matches.small && setScreen('sm')}
                        {matches.medium && setScreen('md')}
                        {matches.large && setScreen('lg')}
                    </>
                )}
            />
            <ProLayout
                logo={null}
                onCollapse={handleMenuCollapse}
                menuItemRender={(menuItemProps, defaultDom) => {
                    if (menuItemProps.isUrl) {
                        return defaultDom;
                    }
                    return (
                        <span
                            onClick={() => handleMenuItem(dispatch, menuItemProps)}
                            style={{ display: 'block' }}
                        >
                            {defaultDom}
                        </span>
                    );
                }}
                breadcrumbRender={(routers = []) => [
                    {
                        path: '/',
                        breadcrumbName: formatMessage({
                            id: 'menu.home',
                            defaultMessage: 'Home',
                        }),
                    },
                    ...routers,
                ]}
                footerRender={false}
                siderWidth={208}
                // menuDataRender={menuDataRender}
                menuDataRender={() => menuData}
                formatMessage={formatMessage}
                rightContentRender={rightProps => <RightContent {...rightProps} />}
                {...props}
                {...collapsed}
                {...settings}
            >
                {childrenElem || welcomeElem}
            </ProLayout>
        </div>
    );
};

export default connect(({ global, settings, menu: { menuInfo } }: ConnectState) => ({
    // collapsed: global.collapsed,
    collapsed: false,
    showMore: global.showMore,
    settings,
    menuGroup: menuInfo,
}))(BasicLayout);
